package com.jrx.anytxn.param.job.bactchBillCompare.config;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.config.BillCompareConfig;
import com.jrx.anytxn.param.config.PathFileConfig;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.TlBillTransCompareSummary;
import com.jrx.anytxn.param.entity.TlThirdBillSummary;
import com.jrx.anytxn.param.mapper.ext.ExtTlBillTransCompareSummaryMapper;
import com.jrx.anytxn.param.mapper.ext.ExtTlBillTransDetilMapper;
import com.jrx.anytxn.param.mapper.ext.ExtTlBillTransInnerSummaryMapper;
import com.jrx.anytxn.param.mapper.ext.ExtTlThirdBillDetailMapper;
import com.jrx.anytxn.param.mapper.ext.ExtTlThirdBillSummaryMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 外部对账-总分核对job
 *
 * @author : zcc
 * 2020/11/26
 */
@Configuration
@EnableConfigurationProperties(PathFileConfig.class)
public class BatchThirdBillCompareConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(BatchThirdBillCompareConfiguration.class);

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private IOrganizationTableService organizationTableService;

    @Autowired
    private ISegmentService iSegmentService;

    @Resource
    private ExtTlThirdBillSummaryMapper extTlBillThirdSummaryMapper;

    @Resource
    private ExtTlBillTransDetilMapper extTlBillTransDetilMapper;

    @Resource
    private ExtTlBillTransCompareSummaryMapper extTlBillTransCompareSummaryMapper;

    @Resource
    private ExtTlBillTransInnerSummaryMapper extTlBillTransInnerSummaryMapper;

    @Resource
    private ExtTlThirdBillDetailMapper extTlBillThirdDetailMapper;

    @Autowired
    private BillCompareConfig billCompareConfig;

    @Bean
    public Job thirdBillCompareJob() throws IOException {
        return jobBuilderFactory.get("thirdBillCompareJob")
                .start(thirdBillCompareStep()) //文件总分核对
                .next(thirdBillTXNCompareStep()) //文件与TXN系统总数核对
                .build();
    }

    @Bean
    public Step thirdBillCompareStep() throws IOException {
        return stepBuilderFactory.get("thirdBillCompareStep").tasklet(thirdBillCompareTasklet()).build();
    }

    @Bean
    public Tasklet thirdBillCompareTasklet() {
        return (stepContribution, chunkContext) -> {
           /* List<TlBillTransCompareSummary> tlBillTransCompareSummaryList = new ArrayList<>();
            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.XIB_ORG_NUMBER);
            // 设置指定对账日期
            Date today = billCompareConfig.getToday();
            if (Objects.nonNull(today)) {
                org.setToday(today);
            }
            String thirdChannel = billCompareConfig.getThirdChannel();
            String businessDate = DateUtils.format(org.getToday());

            logger.info("文件总分核对开始。。。,业务日期为:{}", businessDate);
            //删除当日对账数据，支持重跑
            extTlBillTransCompareSummaryMapper.deleteByBusDateAndThirdChannel(org.getToday(), thirdChannel);

            List<TlThirdBillSummary> summaries = extTlBillThirdSummaryMapper.selectByTenantIdAndBusDate(org.getToday(), org.getTenantId(), thirdChannel);
            if (CollectionUtils.isNotEmpty(summaries)) {
                //总金额
                BigDecimal totalAmount = summaries.stream().map(TlThirdBillSummary::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //总笔数
                Integer totalCount = summaries.stream().map(TlThirdBillSummary::getTotalCount).reduce(0, Integer::sum);

                tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(totalCount, totalAmount, org));

                // 交易类型(01 退货 02 撤销 03 冲正 04 消费)
                //消费总金额
                BigDecimal consumptionAmount = summaries.stream().map(TlThirdBillSummary::getConsumptionAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //消费总笔数
                Integer consumptionCount = summaries.stream().map(TlThirdBillSummary::getConsumptionCount).reduce(0, Integer::sum);
                //消费成功金额
                BigDecimal consumptionSuccessAmount = summaries.stream().map(TlThirdBillSummary::getConsumptionSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //消费成功笔数
                Integer consumptionSuccessCount = summaries.stream().map(TlThirdBillSummary::getConsumptionSuccessCount).reduce(0, Integer::sum);

                tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(consumptionCount, consumptionAmount, consumptionSuccessCount, consumptionSuccessAmount, Constant.TRANSACTION_TYPE_XF, Constant.TRANSACTION_TYPE_XF, org));

                //退货总笔数
                Integer returnCount = summaries.stream().map(TlThirdBillSummary::getReturnCount).reduce(0, Integer::sum);
                //退货总金额
                BigDecimal returnAmount = summaries.stream().map(TlThirdBillSummary::getReturnAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //退货成功笔数
                Integer returnSuccessCount = summaries.stream().map(TlThirdBillSummary::getReturnSuccessCount).reduce(0, Integer::sum);
                //退货成功金额
                BigDecimal returnSuccessAmount = summaries.stream().map(TlThirdBillSummary::getReturnSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(returnCount, returnAmount, returnSuccessCount, returnSuccessAmount, Constant.TRANSACTION_TYPE_TK, Constant.TRANSACTION_TYPE_TK, org));

                //撤销总笔数
                Integer revokeCount = summaries.stream().map(TlThirdBillSummary::getRevokeCount).reduce(0, Integer::sum);
                //总金额
                BigDecimal revokeAmount = summaries.stream().map(TlThirdBillSummary::getRevokeAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //成功笔数
                Integer revokeSuccessCount = summaries.stream().map(TlThirdBillSummary::getRevokeSuccessCount).reduce(0, Integer::sum);
                //成功金额
                BigDecimal revokeSuccessAmount = summaries.stream().map(TlThirdBillSummary::getRevokeSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(revokeCount, revokeAmount, revokeSuccessCount, revokeSuccessAmount, Constant.TRANSACTION_TYPE_CX, Constant.TRANSACTION_TYPE_CX, org));

                //冲正总笔数
                Integer rectificationCount = summaries.stream().map(TlThirdBillSummary::getRectificationCount).reduce(0, Integer::sum);
                //总金额
                BigDecimal rectificationAmount = summaries.stream().map(TlThirdBillSummary::getRectificationAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //成功笔数
                Integer rectificationSuccessCount = summaries.stream().map(TlThirdBillSummary::getRectificationSuccessCount).reduce(0, Integer::sum);
                //成功金额
                BigDecimal rectificationSuccessAmount = summaries.stream().map(TlThirdBillSummary::getRectificationSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(rectificationCount, rectificationAmount, rectificationSuccessCount, rectificationSuccessAmount, Constant.TRANSACTION_TYPE_CZ, Constant.TRANSACTION_TYPE_CZ, org));

                if (CollectionUtils.isNotEmpty(tlBillTransCompareSummaryList)) {
                    extTlBillTransCompareSummaryMapper.insertbatch(tlBillTransCompareSummaryList);
                }
            }

            logger.info("账务文件总分核对结束。。。,业务日期为:{}", businessDate);*/
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step thirdBillTXNCompareStep() {
        return stepBuilderFactory.get("thirdBillTXNCompareStep").tasklet(thirdBillTXNCompareTasklet()).build();
    }

    @Bean
    public Tasklet thirdBillTXNCompareTasklet() {
        return (stepContribution, chunkContext) -> {
            /*List<TlBillTransCompareSummary> tlBillTransCompareSummaryList = new ArrayList<>();

            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.XIB_ORG_NUMBER);
            // 设置指定对账日期
            Date today = billCompareConfig.getToday();
            if (Objects.nonNull(today)) {
                org.setToday(today);
            }
            String thirdChannel = billCompareConfig.getThirdChannel();
            String businessDate = DateUtils.format(org.getToday());
            // 交易类型(01 退货 02 撤销 03 冲正 04 消费)
            logger.info("文件与TXN系统总数核对开始。。。,业务日期为:{}", businessDate);
            List<TlThirdBillSummary> summaries = extTlBillThirdSummaryMapper.selectByTenantIdAndBusDate(org.getToday(), org.getTenantId(), thirdChannel);
            //消费成功金额
            BigDecimal consumptionSuccessAmount = summaries.stream().map(TlThirdBillSummary::getConsumptionSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            //消费成功笔数
            Integer consumptionSuccessCount = summaries.stream().map(TlThirdBillSummary::getConsumptionSuccessCount).reduce(0, Integer::sum);

            tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(consumptionSuccessCount, consumptionSuccessAmount, org, Constant.TRANSACTION_TYPE_XF, Constant.TRANSACTION_TYPE_XF));

            //退货成功笔数
            Integer returnSuccessCount = summaries.stream().map(TlThirdBillSummary::getReturnSuccessCount).reduce(0, Integer::sum);
            //退货成功金额
            BigDecimal returnSuccessAmount = summaries.stream().map(TlThirdBillSummary::getReturnSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

            tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(returnSuccessCount, returnSuccessAmount, org, Constant.TRANSACTION_TYPE_TK, Constant.TRANSACTION_TYPE_TK));

            //撤销成功笔数
            Integer revokeSuccessCount = summaries.stream().map(TlThirdBillSummary::getRevokeSuccessCount).reduce(0, Integer::sum);
            //撤销成功金额
            BigDecimal revokeSuccessAmount = summaries.stream().map(TlThirdBillSummary::getRevokeSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            //冲正成功笔数
            Integer rectificationSuccessCount = summaries.stream().map(TlThirdBillSummary::getRectificationSuccessCount).reduce(0, Integer::sum);
            //冲正成功金额
            BigDecimal rectificationSuccessAmount = summaries.stream().map(TlThirdBillSummary::getRectificationSuccessAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            tlBillTransCompareSummaryList.add(buildBillTransCompareSummary(revokeSuccessCount + rectificationSuccessCount,
                    revokeSuccessAmount.add(rectificationSuccessAmount), org, Constant.TRANSACTION_TYPE_CX, Constant.TRANSACTION_TYPE_CX));

            if (CollectionUtils.isNotEmpty(tlBillTransCompareSummaryList)) {
                extTlBillTransCompareSummaryMapper.insertbatch(tlBillTransCompareSummaryList);
            }

            logger.info("文件与TXN系统总数核对结束。。。,业务日期为:{}", businessDate);*/
            return RepeatStatus.FINISHED;
        };
    }

    private TlBillTransCompareSummary buildBillTransCompareSummary(Integer totalCount, BigDecimal totalAmount, PrOrganizationTable org) throws SegmentException {
        String comDescPre = "[文件内部总分核对]";
        TlBillTransCompareSummary tlBillTransCompareSummary = new TlBillTransCompareSummary();

        Date date = DateUtils.parseDate(DateUtils.format(org.getToday(), DateUtils.DATE_PATTERN), DateUtils.DATE_PATTERN);
        // todo 是否只是统计成功的？
        Integer detailTotalCount = Optional.ofNullable(extTlBillThirdDetailMapper.countByBusinessDate(org.getTenantId(), date, billCompareConfig.getThirdChannel())).orElse(0);
        // todo 是否只是统计成功的？
        BigDecimal detailYTotalAmount = Optional.ofNullable(extTlBillThirdDetailMapper.sumByBusinessDate(org.getTenantId(), date, billCompareConfig.getThirdChannel())).orElse(BigDecimal.ZERO);

        tlBillTransCompareSummary.setId(iSegmentService.getId("TlBillTransCompareSummary"));
        tlBillTransCompareSummary.setTenantId(org.getTenantId());
        tlBillTransCompareSummary.setOrganizationId(org.getOrganizationId());
        tlBillTransCompareSummary.setBillType(Constant.TRANSACTION_TYPE_SUM);
        tlBillTransCompareSummary.setCompareType(Constant.COMPARE_TYPE_0);
        tlBillTransCompareSummary.setSummaryTotalCount(totalCount);
        tlBillTransCompareSummary.setSummaryTotalAmount(totalAmount);
        tlBillTransCompareSummary.setSummarySuccessCount(totalCount);
        tlBillTransCompareSummary.setSummarySuccessAmount(totalAmount);
        tlBillTransCompareSummary.setDetailTotalCount(detailTotalCount);
        tlBillTransCompareSummary.setDetailTotalAmount(detailYTotalAmount);
        tlBillTransCompareSummary.setDetailSuccessCount(detailTotalCount);
        tlBillTransCompareSummary.setDetailSuccessAmount(detailYTotalAmount);
        tlBillTransCompareSummary.setBusinessDate(org.getToday());
        tlBillTransCompareSummary.setThirdChannel(billCompareConfig.getThirdChannel());
        if (!detailTotalCount.equals(totalCount) || detailYTotalAmount.compareTo(totalAmount) != 0) {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_0);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账不平");
        } else {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_1);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账平");
        }
        return tlBillTransCompareSummary;
    }

    private TlBillTransCompareSummary buildBillTransCompareSummary(Integer totalCount, BigDecimal totalAmount, Integer successCount, BigDecimal successAmount,
                                                                   String type, String billType, PrOrganizationTable org) throws SegmentException {
        String comDescPre = "[文件内部明细总分核对]";
        TlBillTransCompareSummary tlBillTransCompareSummary = new TlBillTransCompareSummary();
        String tenantId = org.getTenantId();
        Date today = org.getToday();
        // todo 是否只是统计成功的？
        Integer detailTotalCount = Optional.ofNullable(extTlBillThirdDetailMapper.countByBusinessDateAndType(tenantId, today, type, billCompareConfig.getThirdChannel())).orElse(0);
        // todo 是否只是统计成功的？
        BigDecimal detailYTotalAmount = Optional.ofNullable(extTlBillThirdDetailMapper.sumByBusinessDateAndType(tenantId, today, type, billCompareConfig.getThirdChannel())).orElse(BigDecimal.ZERO);
        String status = "000000000";
        if ("C63-WL".equals(billCompareConfig.getThirdChannel()) || "C63-YL".equals(billCompareConfig.getThirdChannel())) {
            status = "0";
        }
        Integer detailSuccessCount = Optional.ofNullable(extTlBillThirdDetailMapper.countByBusinessDateAndTypeAndStatus(tenantId, today, type, status, billCompareConfig.getThirdChannel())).orElse(0);

        BigDecimal detailSuccessAmount = Optional.ofNullable(extTlBillThirdDetailMapper.sumByBusinessDateAndTypeAndStatus(tenantId, today, type, status, billCompareConfig.getThirdChannel())).orElse(BigDecimal.ZERO);

        tlBillTransCompareSummary.setId(iSegmentService.getId("TlBillTransCompareSummary"));
        tlBillTransCompareSummary.setTenantId(tenantId);
        tlBillTransCompareSummary.setOrganizationId(org.getOrganizationId());
        tlBillTransCompareSummary.setBillType(billType);
        tlBillTransCompareSummary.setCompareType(Constant.COMPARE_TYPE_0);
        tlBillTransCompareSummary.setSummaryTotalCount(totalCount);
        tlBillTransCompareSummary.setSummaryTotalAmount(totalAmount);
        tlBillTransCompareSummary.setSummarySuccessCount(successCount);
        tlBillTransCompareSummary.setSummarySuccessAmount(successAmount);
        tlBillTransCompareSummary.setDetailTotalCount(detailTotalCount);
        tlBillTransCompareSummary.setDetailTotalAmount(detailYTotalAmount);
        tlBillTransCompareSummary.setDetailSuccessCount(detailSuccessCount);
        tlBillTransCompareSummary.setDetailSuccessAmount(detailSuccessAmount);
        tlBillTransCompareSummary.setBusinessDate(today);
        tlBillTransCompareSummary.setThirdChannel(billCompareConfig.getThirdChannel());
        if (!detailTotalCount.equals(totalCount)
                || detailYTotalAmount.compareTo(totalAmount) != 0
                || !detailSuccessCount.equals(successCount)
                || detailSuccessAmount.compareTo(successAmount) != 0) {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_0);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账不平");
        } else {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_1);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账平");
        }
        return tlBillTransCompareSummary;
    }

    private TlBillTransCompareSummary buildBillTransCompareSummary(Integer successCount, BigDecimal successAmount
            , PrOrganizationTable org, String type, String billType) throws SegmentException {

        String comDescPre = "[文件总数与TXN总数核对]";

        TlBillTransCompareSummary tlBillTransCompareSummary = new TlBillTransCompareSummary();
        String tenantId = org.getTenantId();
        Date today = org.getToday();
        Integer txnCount = Optional.ofNullable(extTlBillTransInnerSummaryMapper.countByTenantIdBusDateAndInnerStatusAndBillType(
                tenantId, today, Constant.TRANSFER_SUM_STATUS_S, type, billCompareConfig.getThirdChannel())).orElse(0);

        BigDecimal txnAmount = Optional.ofNullable(extTlBillTransInnerSummaryMapper.sumByTenantIdBusDateAndInnerStatusAndBillType(
                tenantId, today, Constant.TRANSFER_SUM_STATUS_S, type, billCompareConfig.getThirdChannel())).orElse(BigDecimal.ZERO);

        tlBillTransCompareSummary.setId(iSegmentService.getId("TlBillTransCompareSummary"));
        tlBillTransCompareSummary.setTenantId(tenantId);
        tlBillTransCompareSummary.setOrganizationId(org.getOrganizationId());
        tlBillTransCompareSummary.setBillType(billType);
        tlBillTransCompareSummary.setCompareType(Constant.COMPARE_TYPE_1);
        tlBillTransCompareSummary.setSummaryTotalCount(txnCount);
        tlBillTransCompareSummary.setSummaryTotalAmount(txnAmount);
        tlBillTransCompareSummary.setSummarySuccessCount(txnCount);
        tlBillTransCompareSummary.setSummarySuccessAmount(txnAmount);
        tlBillTransCompareSummary.setDetailTotalCount(successCount);
        tlBillTransCompareSummary.setDetailTotalAmount(successAmount);
        tlBillTransCompareSummary.setDetailSuccessCount(successCount);
        tlBillTransCompareSummary.setDetailSuccessAmount(successAmount);
        tlBillTransCompareSummary.setBusinessDate(today);
        tlBillTransCompareSummary.setThirdChannel(billCompareConfig.getThirdChannel());
        if (!successCount.equals(txnCount) || successAmount.compareTo(txnAmount) != 0) {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_0);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账不平");
        } else {
            tlBillTransCompareSummary.setCompareStatus(Constant.COMPARE_FLAG_1);
            tlBillTransCompareSummary.setCompareDesc(comDescPre + "账平");
        }
        return tlBillTransCompareSummary;
    }
}